package com.sobey.web.config;

import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.sobey.web.core.SB_InitializingInterceptor;
import com.sobey.web.core.SB_PropertyEditorRegistrar;
import com.sobey.web.core.SB_SimpleMappingExceptionResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.sobey.web.function", useDefaultFilters = false, includeFilters = { 
		@ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class}) })
public class MvcConfig extends WebMvcConfigurationSupport {
	
	private static final Logger LOGGER = Logger.getLogger(MvcConfig.class);
	
	/**
	 * 注册视图处理器
	 * @return
	 */
	@Bean
	public ViewResolver viewResolver() {
		LOGGER.info("注册视图处理器viewResolver");
		
		InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/views/");
		viewResolver.setSuffix(".jsp");
		
		return viewResolver;
	}
	
	/**
	 * 注册消息资源处理器
	 * @return
	 */
	@Bean
	public MessageSource messageSource() {
		LOGGER.info("注册消息资源处理器messageSource");
		
		ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
		messageSource.setBasename("config.messages.messages");
		
		return messageSource;
	}
	
	 /**                                                          
	    * 描述 : <本地化拦截器>. <br> 
	    *<p> 
	    	<使用方法说明>  
	     </p>                                                                                                                                                                                                                                                
	    * @return                                                                                                      
	    */  
	    @Bean
	    public LocaleChangeInterceptor localeChangeInterceptor(){
	    	LOGGER.info("LocaleChangeInterceptor");
	    	return new LocaleChangeInterceptor();
	    }
	    
	    /**                                                          
	    * 描述 : <基于cookie的本地化资源处理器>. <br> 
	    *<p> 
	    	<使用方法说明>  
	     </p>                                                                                                                                                                                                                                                
	    * @return                                                                                                      
	    */  
	    @Bean(name="localeResolver")
	    public CookieLocaleResolver cookieLocaleResolver(){
	    	LOGGER.info("CookieLocaleResolver");
	    	return new CookieLocaleResolver();
	    }
	    
	    /**                                                          
	    * 描述 : <注册自定义拦截器>. <br> 
	    *<p> 
	    	<使用方法说明>  
	     </p>                                                                                                                                                                                                                                                
	    * @return                                                                                                      
	    */  
	    @Bean
	    public SB_InitializingInterceptor initializingInterceptor(){
	    	LOGGER.info("CP_InitializingInterceptor");
	    	return new SB_InitializingInterceptor();
	    }
	    
	    
	    /**                                                          
	     * 描述 : <RequestMappingHandlerMapping需要显示声明，否则不能注册自定义的拦截器>. <br> 
	     *<p> 
	     	<这个比较奇怪,理论上应该是不需要的>  
	      </p>                                                                                                                                                                                                                                                
	     * @return                                                                                                      
	     */ 
	    @Bean
		public RequestMappingHandlerMapping requestMappingHandlerMapping() {
	    	LOGGER.info("RequestMappingHandlerMapping");
			
			return super.requestMappingHandlerMapping();
		}

	    /**                                                          
	    * 描述 : <添加拦截器>. <br> 
	    *<p> 
	    	<使用方法说明>  
	     </p>                                                                                                                                                                                                                                                
	    * @param registry                                                                                                      
	    */  
		protected void addInterceptors(InterceptorRegistry registry) {
	    	LOGGER.info("addInterceptors start");
			registry.addInterceptor(localeChangeInterceptor());
			registry.addInterceptor(initializingInterceptor());
			LOGGER.info("addInterceptors end");
		}

	    /**                                                          
	     * 描述 : <HandlerMapping需要显示声明，否则不能注册资源访问处理器>. <br> 
	     *<p> 
	     	<这个比较奇怪,理论上应该是不需要的>  
	      </p>                                                                                                                                                                                                                                                
	     * @return                                                                                                      
	     */ 
	    @Bean
		public HandlerMapping resourceHandlerMapping() {
	    	LOGGER.info("HandlerMapping");
	    	return super.resourceHandlerMapping();
	    }
	    
	    /**                                                          
	     * 描述 : <资源访问处理器>. <br> 
	     *<p> 
	     	<可以在jsp中使用/static/**的方式访问/WEB-INF/static/下的内容>  
	      </p>                                                                                                                                                                                                                                                
	     * @param registry                                                                                                      
	     */  
		protected void addResourceHandlers(ResourceHandlerRegistry registry) {
			LOGGER.info("addResourceHandlers");
	        registry.addResourceHandler("/static/**").addResourceLocations("/static/");
	        registry.addResourceHandler("/bower_components/**").addResourceLocations("/bower_components/");
	        registry.addResourceHandler("/components/**").addResourceLocations("/components/");
	        registry.addResourceHandler("/views/**").addResourceLocations("/views/");
	        registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
	    }
	    
		/**                                                          
		* 描述 : <文件上传处理器>. <br> 
		*<p> 
			<使用方法说明>  
		 </p>                                                                                                                                                                                                                                                
		* @return                                                                                                      
		*/  
		@Bean(name="multipartResolver")
		public CommonsMultipartResolver commonsMultipartResolver(){
			LOGGER.info("CommonsMultipartResolver");
			return new CommonsMultipartResolver();
		}
		
		/**                                                          
		* 描述 : <异常处理器>. <br> 
		*<p> 
			<系统运行时遇到指定的异常将会跳转到指定的页面>  
		 </p>                                                                                                                                                                                                                                                
		* @return                                                                                                      
		*/  
		@Bean(name="exceptionResolver")
		public SB_SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
			LOGGER.info("CP_SimpleMappingExceptionResolver");
			
			SB_SimpleMappingExceptionResolver simpleMappingExceptionResolver= new SB_SimpleMappingExceptionResolver();
			simpleMappingExceptionResolver.setDefaultErrorView("common_error");
			simpleMappingExceptionResolver.setExceptionAttribute("exception");
			Properties properties = new Properties();
			properties.setProperty("java.lang.RuntimeException", "common_error");
			simpleMappingExceptionResolver.setExceptionMappings(properties);
			return simpleMappingExceptionResolver;
		}
		
		 /**                                                          
	     * 描述 : <RequestMappingHandlerAdapter需要显示声明，否则不能注册通用属性编辑器>. <br> 
	     *<p> 
	     	<这个比较奇怪,理论上应该是不需要的>  
	      </p>                                                                                                                                                                                                                                                
	     * @return                                                                                                      
	     */ 
		@Bean
		public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
			LOGGER.info("RequestMappingHandlerAdapter");
	    	return super.requestMappingHandlerAdapter();
		}
		
		/**                                                          
		* 描述 : <注册通用属性编辑器>. <br> 
		*<p> 
			<这里只增加了字符串转日期和字符串两边去空格的处理>  
		 </p>                                                                                                                                                                                                                                                
		* @return                                                                                                      
		*/  
		protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
			LOGGER.info("ConfigurableWebBindingInitializer");
			ConfigurableWebBindingInitializer initializer = super.getConfigurableWebBindingInitializer();
			SB_PropertyEditorRegistrar register = new SB_PropertyEditorRegistrar();
			register.setFormat("yyyy-MM-dd");
			initializer.setPropertyEditorRegistrar(register);
			return initializer;
		}
}
